/**
 * Notes: 导出模块后台管理-控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux@qq.com
 * Date: 2022-01-15 10:20:00 
 */

const BaseAdminController = require('./base_admin_controller.js');
const AdminExportService = require('../../service/admin/admin_export_service.js');

class AdminExportController extends BaseAdminController {
	// 覆盖构造函数：允许在无 OPENID 的云函数触发场景下使用匿名身份
	constructor(route, openId, event) {
		super(route, openId || 'anonymous_user', event);
	}

	// 覆盖初始化以避免本地运行时触发数据库初始化
	async initSetup() {
		// 空实现，导出任务不需要初始化业务配置
		return;
	}

	/**************报名数据导出 BEGIN ********************* */
	/** 当前是否有导出文件生成 */
	async joinDataGet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			isDel: 'int|must', //是否删除已有记录
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminExportService();

		if (input.isDel === 1)
			await service.deleteJoinDataExcel(); //先删除

		return await service.getJoinDataURL();
	}

	/** 导出数据 */
	async joinDataExport() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			meetId: 'id|must',
			startDay: 'date|must',
			endDay: 'date|must',
			status: 'int|must|default=1'
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminExportService();
		return await service.exportJoinDataExcel(input);
	}

	/** 删除导出的报名数据文件 */
	async joinDataDel() {
		await this.isAdmin();

		// 数据校验
		let rules = {};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminExportService();
		return await service.deleteJoinDataExcel();
	}

	/************** 用户数据导出 BEGIN ********************* */
	/** 当前是否有导出文件生成 */
	async userDataGet() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			isDel: 'int|must', //是否删除已有记录
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminExportService();

		if (input.isDel === 1)
			await service.deleteUserDataExcel(); //先删除 
	
		return await service.getUserDataURL();
	}

	/** 导出数据 */
	async userDataExport() {
		await this.isAdmin();

		// 数据校验
		let rules = {
			condition: 'string|name=导出条件',
		};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminExportService();
		return await service.exportUserDataExcel(input.condition);
	}

	/** 删除导出的用户数据 */
	async userDataDel() {
		await this.isAdmin();

		// 数据校验
		let rules = {};

		// 取得数据
		let input = this.validateData(rules);

		let service = new AdminExportService();
		return await service.deleteUserDataExcel();
	}


	/**
	 * 导出所有集合为 JSON 并上传到云存储
	 * 注意：该接口不校验管理员，便于在云函数运行时直接触发
	 */
	async exportAllCollectionsJson() {
		// 读取集合名
		const config = require('../../../config/config.js');
		const timeUtil = require('../../../framework/utils/time_util.js');
		const dbUtil = require('../../../framework/database/db_util.js');
		const cloudBase = require('../../../framework/cloud/cloud_base.js');
		const cloudUtil = require('../../../framework/cloud/cloud_util.js');

		const collectionsStr = config.COLLECTION_NAME || '';
		const names = collectionsStr.split('|').map(s => s.trim()).filter(Boolean);
		if (!names.length) return { success: false, message: '未配置集合名称' };

		const cloud = cloudBase.getCloud();
		const ts = timeUtil.time('YMDhms');
		const basePath = `${config.DATA_EXPORT_PATH}json/${ts}/`;

		let results = [];
		for (const name of names) {
			try {
				// 拉取集合所有数据
				const dataList = await dbUtil.getAllBig(name, {});
				const jsonStr = JSON.stringify(dataList, null, 2);
				const buffer = Buffer.from(jsonStr, 'utf8');

				const cloudPath = `${basePath}${name}.json`;
				let upload = await cloud.uploadFile({
					cloudPath,
					fileContent: buffer,
				});

				let fileID = upload && upload.fileID ? upload.fileID : '';
				let url = fileID ? await cloudUtil.getTempFileURLOne(fileID) : '';
				results.push({ collection: name, count: dataList.length, cloudPath, fileID, url });
			} catch (err) {
				results.push({ collection: name, error: err && err.message ? err.message : String(err) });
			}
		}

		return { success: true, total: names.length, files: results };
	}

	/**
	 * 从云存储导入种子数据到数据库
	 * 注意：该接口不校验管理员，便于在云函数运行时直接触发
	 * 可选参数：basePath 云存储中的种子文件目录，默认 'seed/database/'
	 */
	async importSeedData() {
		const config = require('../../../config/config.js');
		const cloudBase = require('../../../framework/cloud/cloud_base.js');
		const dbUtil = require('../../../framework/database/db_util.js');

		// 允许通过路由参数覆盖存储路径
		let rules = { basePath: 'string|name=云存储基路径|default=seed/database/' };
		let input = this.validateData(rules);
		const basePath = input.basePath || 'seed/database/';

		// 读取集合名与允许列表
		const collectionsStr = config.COLLECTION_NAME || '';
		const allowNames = collectionsStr.split('|').map(s => s.trim()).filter(Boolean);
		if (!allowNames.length) return { success: false, message: '未配置集合名称' };

		// 只导入存在种子文件的集合（文件名规则：<collection>.seed.json）
		const seedTargets = [
			'ax_admin',
			'ax_devices',
			'ax_employees',
			'ax_foster_rooms',
			'ax_news',
			'ax_recharge_packages',
			'ax_services',
			'ax_stores',
			'ax_user_coupons'
		].filter(n => allowNames.includes(n));

		const cloud = cloudBase.getCloud();
		const db = cloud.database();

		let results = [];
		for (const name of seedTargets) {
			const fileID = `cloud://${config.CLOUD_ID}/${basePath}${name}.seed.json`;
			try {
				// 下载并解析种子 JSON
				const dl = await cloud.downloadFile({ fileID });
				const buf = dl && dl.fileContent ? dl.fileContent : null;
				if (!buf) throw new Error('未读取到文件内容');
				let jsonStr = Buffer.isBuffer(buf) ? buf.toString('utf-8') : String(buf);
				const dataArr = JSON.parse(jsonStr);
				if (!Array.isArray(dataArr)) throw new Error('种子文件格式必须为数组');

				// 确保集合存在
				const exist = await dbUtil.isExistCollection(name);
				if (!exist) await dbUtil.createCollection(name);

				let succ = 0, fail = 0;
				let errors = [];
				for (const item of dataArr) {
					let doc = { ...item };
					if (doc._id) delete doc._id; // 避免 _id 写入错误
					try {
						await db.collection(name).add(doc);
						succ++;
					} catch (e) {
						fail++;
						errors.push(e && e.message ? e.message : String(e));
					}
				}

				results.push({ collection: name, fileID, total: dataArr.length, success: succ, failed: fail });
			} catch (err) {
				results.push({ collection: name, fileID, error: err && err.message ? err.message : String(err) });
			}
		}

		return { success: true, basePath, results };
	}

	/**
	 * 使用内嵌数据导入种子数据到数据库
	 * 调用独立的种子数据导入脚本
	 */
	async importSeedDataEmbedded() {
		try {
			// 调用我们创建的内嵌数据脚本
			const importScript = require('../../../database/import_seed_data.js');
			const result = await importScript.main({}, {});
			return result;
		} catch (err) {
			console.error('导入种子数据失败:', err);
			return {
				success: false,
				message: '种子数据导入失败',
				error: err.message || String(err)
			};
		}
	}
}

module.exports = AdminExportController;